#pragma once

#include <string>
#include <vector>
#include <future>
#include <atomic>
#include "SDL2/SDL.h"
#include <glew/GL/glew.h>
#include "SDL2/SDL_opengl.h"
#include "SDL2/SDL_ttf.h"
#include "glm/glm.hpp"
#include "DGGSVisualizer.hpp"

_NNU_DGGS_BEGIN
namespace DGGSViewer {

// 定义色带类型
enum class ColorMapType {
    RGB,           // 多波段直接对应RGB
    JET,           // 蓝-青-黄-红
    VIRIDIS,       // 蓝紫-绿-黄
    PLASMA,        // 紫-橙-黄
    INFERNO,       // 黑-紫-橙-黄
    MAGMA,         // 黑-紫-粉-黄
    GRAYSCALE      // 灰度
};

// 定义经纬度结构体
struct GeoCoordinate {
    double lat;  // 纬度
    double lon;  // 经度
    bool isValid;  // 是否有效
};

// 定义经纬度标注结构体
struct GridLabel {
    float x, y, z;   // 标注位置
    std::string text; // 标注文本
    bool isLongitude; // 是否为经度标注（true=经度，false=纬度）
};

class Earth {
public:
    Earth();
    ~Earth();
    
    bool initialize();
    void render();
    void loadData(const std::string& filePath);
    void loadMultipleData(const std::vector<std::string>& filePaths);
    
    // 添加鼠标控制相关方法
    void handleMouseWheel(float yOffset);
    void handleMouseDrag(int xRel, int yRel, bool isLeftButton);
    void resetView();
    
    // 添加鼠标点击方法，获取经纬度
    GeoCoordinate handleMouseClick(int x, int y);
    
    // 添加调整投影矩阵的方法
    void updateProjection(int windowWidth, int windowHeight);
    
    // 添加键盘处理方法
    void handleKeyboard(SDL_Keycode key);
    
    // 获取当前选中的经纬度
    GeoCoordinate getSelectedCoordinate() const { return m_selectedCoordinate; }
    
    // 调整覆盖数据的透明度
    void adjustOverlayAlpha(float delta);

    // 切换快捷键说明的显示/隐藏
    void toggleHelpText() { m_showHelpText = !m_showHelpText; }
    
    // 获取是否显示快捷键说明
    bool isHelpTextShown() const { return m_showHelpText; }
    
    // 切换经纬网显示/隐藏
    void toggleGrid() { m_showGrid = !m_showGrid; }
    
    // 获取是否显示经纬网
    bool isGridShown() const { return m_showGrid; }
    
    // 切换经纬度标注显示/隐藏
    void toggleGridLabels() { m_showGridLabels = !m_showGridLabels; }
    
    // 获取是否显示经纬度标注
    bool isGridLabelsShown() const { return m_showGridLabels; }
    
private:
    bool loadTexture(const std::string& texturePath);
    void createSphere(float radius, unsigned int rings, unsigned int sectors);
    void renderEarth();
    void renderOverlayData();
    void renderCoordinateLabel();
    void renderHelpText(); // 渲染快捷键说明
    void renderGrid(); // 渲染经纬网
    void renderGridLabels(float longitudeStep, float latitudeStep); // 渲染经纬网标注
    
    // 创建经纬网
    void createGrid();
    
    // 根据缩放级别创建自适应密度的经纬网
    void createAdaptiveGrid(float zoomLevel);

    // 在3D空间中渲染文本
    void renderText3D(const std::string& text, float x, float y, float z, 
                      const glm::vec3& color, float scale);
    
    // 获取基于缩放级别的经纬度间隔
    float getLongitudeStep(float zoomLevel) const;
    float getLatitudeStep(float zoomLevel) const;
    
    // 判断是否需要更新经纬网
    bool needGridUpdate() const;
    
    // 初始化TTF
    bool initTTF();
    // 创建帮助面板纹理
    bool createHelpPanelTexture();
    
    // 将屏幕坐标转换为经纬度
    GeoCoordinate screenToGeo(int x, int y);
    
    // 添加生成覆盖数据的方法
    void generateOverlayData();

    // 添加色带映射方法
    glm::vec3 applyColorMap(float value, ColorMapType colorMapType);

    GLuint m_vao;
    GLuint m_vbo;
    GLuint m_ebo;
    GLuint m_texture;
    GLuint m_shaderProgram;
    GLuint m_overlayShaderProgram;  // 添加覆盖数据的着色器程序
    GLuint m_computeShaderProgram;  // 计算着色器程序
    
    std::vector<float> m_vertices;
    std::vector<unsigned int> m_indices;
    
    float m_rotationAngle;
    glm::mat4 m_modelMatrix;
    glm::mat4 m_viewMatrix;
    glm::mat4 m_projectionMatrix;
    
    // 鼠标控制相关属性
    float m_zoom;
    float m_rotationX;
    float m_rotationY;
    bool m_autoRotate;
    
    // 数据可视化相关
    std::vector<float> m_overlayData;
    GLuint m_overlayVBO;
    bool m_hasOverlayData;
    float m_overlayAlpha;  // 覆盖数据的透明度

    // 异步处理相关
    std::future<void> m_overlayDataFuture;
    std::atomic<bool> m_overlayDataReady;
    std::mutex m_overlayDataMutex;
    
    // 色带相关
    ColorMapType m_currentColorMap;
    
    DGGSVisualizer* m_dggsVisualizer;
    
    // 经纬度显示相关
    GeoCoordinate m_selectedCoordinate;
    bool m_showCoordinateLabel;
    int m_windowWidth;
    int m_windowHeight;
    
    // 快捷键说明相关
    bool m_showHelpText;  // 是否显示快捷键说明
    GLuint m_helpTextVAO; // 用于渲染快捷键说明的VAO
    GLuint m_helpTextVBO; // 用于渲染快捷键说明的VBO
    GLuint m_helpTextShaderProgram; // 快捷键说明的着色器程序
    
    // 文本渲染相关
    TTF_Font* m_font;  // TTF字体
    GLuint m_helpPanelTexture; // 帮助面板的整体纹理
    bool m_helpPanelNeedsUpdate; // 标记帮助面板是否需要更新
    GLuint m_panelVAO; // 用于面板渲染的VAO
    GLuint m_panelVBO; // 用于面板渲染的VBO
    GLuint m_panelEBO; // 用于面板渲染的EBO
    
    // 经纬网相关
    bool m_showGrid;  // 是否显示经纬网
    GLuint m_gridVAO; // 用于渲染经纬网的VAO
    GLuint m_gridVBO; // 用于渲染经纬网的VBO
    std::vector<float> m_gridData; // 经纬网的顶点数据
    float m_lastGridZoom;  // 上次创建经纬网时的缩放级别
    float m_gridZoomThreshold; // 触发经纬网更新的缩放差值阈值
    
    // 经纬网标注相关
    bool m_showGridLabels;  // 是否显示经纬网标注
    std::vector<GridLabel> m_gridLabels; // 经纬网标注数据
    GLuint m_labelTextureAtlas; // 标注文本纹理图集
};

}
_NNU_DGGS_END